package cn.wolfcode.wolf2w.service.impl;


import cn.wolfcode.wolf2w.domain.Destination;
import cn.wolfcode.wolf2w.domain.Travel;
import cn.wolfcode.wolf2w.domain.UserInfo;
import cn.wolfcode.wolf2w.exception.LogicException;
import cn.wolfcode.wolf2w.query.TravelQueryObject;
import cn.wolfcode.wolf2w.repository.TravelRepository;
import cn.wolfcode.wolf2w.service.IDestinationService;
import cn.wolfcode.wolf2w.service.ITravelService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;

@Service
//@Transactional mongodb事务必须复制集方式
public class TravelServiceImpl implements ITravelService {
    @Autowired
    private TravelRepository repository;
    @Autowired
    private MongoTemplate template;
    @Autowired
    private UserInfoServiceImpl userInfoService;
    @Autowired
    private IDestinationService destinationService;

    @Override
    public void save(Travel travel) {
        travel.setId(null);//防止游标
        repository.save(travel);
    }

    @Override
    public void update(Travel travel) {
        repository.save(travel);
    }

    @Override
    public void delete(String id) {
        repository.deleteById(id);
    }

    @Override
    public Travel get(String id) {
        Travel travel = repository.findById(id).orElse(null);
        UserInfo userInfo = userInfoService.get(travel.getUserId());
        Destination destination = destinationService.get(travel.getDestId());
        travel.setDest(destination);
        travel.setAuthor(userInfo);
        return travel;
    }

    @Override
    public List<Travel> list() {
        return repository.findAll();
    }

    @Override
    public Page<Travel> query(TravelQueryObject qo) {
        //查询的条件对象
        Query query = new Query();
        //拼接条件
        if (qo.getDestId() != null) {
            query.addCriteria(new Criteria().where("destId").is(qo.getDestId()));
        }
        if (qo.getDayType() != null && qo.getDayType() != -1) {
            query.addCriteria(new Criteria().where("day").gt(qo.getMinDay()).lt(qo.getMaxDay()));
        }
        if (qo.getPerExpendType() != null && qo.getPerExpendType() != -1) {
            query.addCriteria(new Criteria().where("perExpend").gt(qo.getMinPerexpend()).lt(qo.getMaxPerexpend()));
        }
        long count = template.count(query, Travel.class);//计算一共有多少条数据 query 为无条件 totalCount  集合MOngoDb
        if (count == 0) {
            return Page.empty();//空的页面对象
        }
        //分页加排序---->条件拼接
        //按照最热排序
        PageRequest pageRequest = PageRequest.of(qo.getCurrentPage() - 1, qo.getPageSize(), Sort.Direction.ASC, "_id");
        if (qo.getOrderType() == 1) {
            pageRequest = PageRequest.of(qo.getCurrentPage() - 1, qo.getPageSize(), Sort.Direction.DESC, "lastUpdateTime");
        }
        //最热
        if (qo.getOrderType() == 2) {
            pageRequest = PageRequest.of(qo.getCurrentPage() - 1, qo.getPageSize(), Sort.Direction.DESC, "viewnum");

        }
        //把条件放入查询对象中
        query.with(pageRequest);
        //查询当前结果集template.find
        List<Travel> list = template.find(query, Travel.class);
        for (Travel travel : list) {
            UserInfo userInfo = userInfoService.get(travel.getUserId());
            travel.setAuthor(userInfo);
        }
        //PageImpl等价于之前的PageResult
        return new PageImpl<>(list, pageRequest, count);//PageResult原生的  pageRequest当前页  多少条数
        //PageHadler  分页插件的
    }

    @Override
    public void audit(String id, Integer state) {
        Travel travel = this.get(id);
//        System.out.println(travel);
        if (state == Travel.STATE_RELEASE) {
            if (travel.getState() == Travel.STATE_RELEASE) {
                throw new LogicException("已经发布！");
            }
            travel.setReleaseTime(new Date());
            travel.setLastUpdateTime(new Date());
            travel.setState(state);
        } else {
            travel.setLastUpdateTime(new Date());
            travel.setState(Travel.STATE_REJECT);
            travel.setReleaseTime(null);
            travel.setState(state);
        }
        repository.save(travel);
    }

    @Override
    public List<Travel> viewnumTop3(String destId) {
        Pageable pageable = PageRequest.of(0, 3, Sort.Direction.DESC, "viewnum");
        return repository.findByDestId(destId, pageable);
    }

    @Override
    public void saveOrUpdate(Travel travel, UserInfo userInfo) {
        //1.目的地的名称
        Destination destination = destinationService.get(travel.getDestId());
        travel.setDestName(destination.getName());
        //2.用户Id
        travel.setUserId(userInfo.getId());
        //@RequireLogin 登陆标签   需要 token ,那么我们从页面 拿到 token
        //通过 之前写的方法,编写 token 来编写
        //3.创建时间
        //travel.setCreateTime(new Date());
        //4.发布时间
        //        发布的时候才设值,所以先不用管
        //5.最后更新时间
        travel.setLastUpdateTime(new Date());
        if (StringUtils.hasLength(travel.getId())) {
            //先通过 id 查询 当前游记信息
            Travel tra = this.get(travel.getId());
            //后替换
            travel.setCreateTime(tra.getCreateTime());   //实际时间
            travel.setViewnum(tra.getViewnum());         //点击数
            travel.setReplynum(tra.getReplynum());       //评论数
            travel.setThumbsupnum(tra.getThumbsupnum());   //点赞数
            travel.setSharenum(tra.getSharenum());       //分享数
            travel.setFavornum(tra.getFavornum());       //收藏数
            //更新
            this.update(travel);
        } else {
            travel.setCreateTime(new Date());
            this.save(travel);
        }
    }

    @Override
    public List<Travel> findByDestId(String id) {
        List<Travel> byDestId = repository.findByDestId(id, null);
        for (Travel travel : byDestId) {
            UserInfo userInfo = userInfoService.get(travel.getUserId());
            travel.setAuthor(userInfo);
        }
        
        return byDestId;
    }


}